package com.example.jianbing.jvm;

/**
 * @ClassName : MyObject
 * @Description :
 * @Author : JB
 * @Date: 2020-08-09 23:57
 */

/***
 * 虚拟机自带的类加载器
 *      1. 启动类加载器（Bootstrap）C++          $JAVAHOME/jre/lib/rt.jar
 *      2. 扩展类加载器（Extension）Java         $JAVAHOME/jre/lib/ext/*.jar
 *      3. 应用程序类加载器（AppClassLoader）     $CLASSPATH
 *          Java也叫系统类加载器，加载当前应用的classpath的所有类
 * 用户自定义加载器
 *      Java.lang.ClassLoader的子类，用户可以定制类的加载方式
 *
 * 双亲委派机制描述
 *      某个特定的类加载器在接到加载类的请求时，首先将加载任务委托给父类加载器，
 *      依次递归，如果父类加载器可以完成类加载任务，就成功返回；只有父类加载器无法
 *      完成此加载任务时，才自己去加载。
 *
 * 能不能自己写个类叫java.lang.System？
 *
 * 答案：通常不可以，但可以采取另类方法达到这个需求。
 * 解释：为了不让我们写System类，类加载采用委托机制，这样可以保证爸爸们优先，爸爸们能找到的类，
 * 儿子就没有机会加载。而System类是Bootstrap加载器加载的，就算自己重写，也总是使用Java系统提供
 * 的System，自己写的System类根本没有机会得到加载。
 *
 * 但是，我们可以自己定义一个类加载器来达到这个目的，为了避免双亲委托机制，
 * 这个类加载器也必须是特殊的。由于系统自带的三个类加载器都加载特定目录下的类，
 * 如果我们自己的类加载器放在一个特殊的目录，那么系统的加载器就无法加载，也就是最终还是由
 * 我们自己的加载器加载。
 */
public class MyObject {
    public static void main(String[] args) {
        Object object = new Object();
        System.out.println("1"+object.getClass().getClassLoader());
        //System.out.println("2"+object.getClass().getClassLoader().getParent());
        //System.out.println("3"+object.getClass().getClassLoader().getParent().getParent());
        System.out.println("----");
        MyObject myObject = new MyObject();
        System.out.println("4"+myObject.getClass().getClassLoader());
        System.out.println("5"+myObject.getClass().getClassLoader().getParent());
        System.out.println("6"+myObject.getClass().getClassLoader().getParent().getParent());
    }
}
